﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace BTalk.Crypto.Algorithms
{
    public class Aes : ICryptoStrategy
    {
        public RijndaelManaged AesCipher { get; set; }

        public Aes(CipherMode mode, byte[] key)
        {
            AesCipher = new RijndaelManaged();
            AesCipher.Mode = mode;
            AesCipher.Padding = PaddingMode.ISO10126;

            if (key != null)
                AesCipher.Key = key;
            else
                AesCipher.GenerateKey();

            Configuration = AesCipher.IV;
        }

        //private byte[] PadKey(byte[] key)
        //{
        //    byte[] buffer = new byte[32];
        //    Array.Copy(key, buffer, key.Length > buffer.Length ? buffer.Length : key.Length);

        //    for (int i = key.Length; i < buffer.Length; i++)
        //    {
        //        buffer[i] = 0;
        //    }

        //    return buffer;

        //}

        public byte[] Encode(byte[] message)
        {
            var cryptoStream = new CryptoStream(new MemoryStream(message), AesCipher.CreateEncryptor(), CryptoStreamMode.Read);
            var buffer = new List<byte>();
            int readByte;

            while ((readByte = cryptoStream.ReadByte()) != -1)
            {
                buffer.Add((byte)readByte);
            }

            return buffer.ToArray();
        }

        public byte[] Decode(byte[] message)
        {
            var cryptoStream = new CryptoStream(new MemoryStream(message), AesCipher.CreateDecryptor(), CryptoStreamMode.Read);
            var buffer = new List<byte>();
            int readByte;

            while ((readByte = cryptoStream.ReadByte()) != -1)
            {
                buffer.Add((byte)readByte);
            }

            return buffer.ToArray();
        }

        public dynamic Configuration
        {
            get
            {
                return AesCipher.IV;
            }
            set
            {
                AesCipher.IV = value;
            }
        }
    }
}
